package com.retail.bbq.cola.aop.sign;

import com.retail.bbq.cola.enums.CommonEnum;
import com.retail.bbq.cola.utils.DateUtil;
import com.retail.bbq.cola.utils.MD5Util;
import com.retail.bbq.cola.vo.ResultVO;
import com.retail.bbq.cola.vo.request.InvokeReq;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

@Aspect
@Component
@Order(1)
@Slf4j
public class ValidateSignInterceptor {
    private static final String timestampStr = "timestamp";
    private static final String appIdStr = "app_id";
    private static final String signStr = "sig";
    private static final String mtRequestIdStr = "mt_request_id";
    public static final String platformTypeStr = "platform_type";
    private static final String separator = "|";
    private static final String separator2 = "_";
    private static final Long timeGap = 10 * 60 * 1000L;
    private static final List<String> methodNames = new ArrayList<String>(){{
        add("orderDataPostBack");
    }};

    @Pointcut("execution(public * com.retail.lottery.colalottery.controller.callback.*.*(..))")
    public void Pointcut() {
    }

    @Around("Pointcut()")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        //1.先校验方法名
        String methodName = point.getSignature().getName();
        if (!methodNames.contains(methodName)) {
            return point.proceed();
        }

        HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
        String timestamp = request.getHeader(timestampStr);
        String sign = request.getHeader(signStr);
        String appId = request.getHeader(appIdStr);
        String platformType = request.getHeader(platformTypeStr);
        String mtRequestId = request.getHeader(mtRequestIdStr);


        if (StringUtils.isBlank(sign) || StringUtils.isBlank(timestamp) || StringUtils.isBlank(appId)|| StringUtils.isBlank(mtRequestId)) {
            return ResultVO.error(CommonEnum.SIGN_ERROR, false);
        }

        LocalDate today = LocalDate.now();
        if (DateUtil.timeGap(today.atStartOfDay(), LocalDateTime.now(), timeGap)
                || !sign.equalsIgnoreCase(MD5Util.getMD5WithoutSlat(platformType + separator + methodName + separator + timestamp))) {
            return ResultVO.error(CommonEnum.SIGN_ERROR, false);
        }
        InvokeReq req = (InvokeReq) point.getArgs()[0];
        req.setMtRequestId(mtRequestId);
        req.setPlatformType(Integer.valueOf(platformType));
        return point.proceed();
    }
}
